package com.car.loan.project.xr.util.repayment;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List;

/**
 * @author huangding
 * @description
 * @date 2019/12/31 11:36
 */
public class RepaymentPlanUtil {

    /**
     * @param lendDate 放贷日期
     * @param statementDay 账单日
     */
    public static String getFirstStatementDate(String lendDate, int statementDay) {
        LocalDate parse = LocalDate.parse(lendDate);
        //获取首期账单日
        int lenDay = parse.getDayOfMonth();
        parse = parse.withDayOfMonth(statementDay);
        if (lenDay > statementDay) {
            parse = parse.plusMonths(1);
        }
        return parse.toString();
    }

    /**
     * 获取最后还款时间
     *
     * @param firstStatementDate 首期账单日
     * @param gracePeriod 银行宽限期
     * @param term 还款期数 首期账单日+还款期数+宽限期
     */
    public static String getLastRepaymentDate(int gracePeriod, long term,
        String firstStatementDate) {
        return LocalDate.parse(firstStatementDate).plusMonths(term).plusDays(gracePeriod)
            .toString();
    }

    /**
     * 获取当前期还款计划
     *
     * @param repaymentPlanParam 获取还款计划参数
     * @param lastRepaymentDate 最后还款时间
     */
    public static RepaymentPlan getCurrentRepaymentPlan(
        RepaymentPlanParam repaymentPlanParam,
        LocalDate lastRepaymentDate) {
        return getCurrentRepaymentPlan(LocalDate.now(), repaymentPlanParam, lastRepaymentDate);
    }

    /**
     * 获取当前还款期数
     */
    public static Long getCurrentRepayTerm(LocalDate now, LocalDate firstRepayDate, Long term) {
        // 还款最后时间
        LocalDate lastRepaymentDate = firstRepayDate.plusMonths(term);
        if (now.compareTo(lastRepaymentDate) > 0) {
            return term;
        }
        long between = ChronoUnit.MONTHS.between(firstRepayDate, now);
        if (between == 0) {
            //第一期
            return 1L;
        } else if (between >= term) {
            // 超过最后还款期
            if (now.compareTo(lastRepaymentDate) > 0) {
                return term;
            } else {
                return term - 1;
            }
        } else {
            //获取对比这个月的账单日
            LocalDate localDate = firstRepayDate.plusMonths(between + 1);
            if (now.compareTo(localDate) >= 0) {
                //大于等于取出的账单日则为取出期数
                //返回对比期数
                return between + 2;
            } else {
                //小于对比期数
                //返回对比上一期
                return between + 1;
            }
        }
    }


    /**
     * 获取当前期还款计划
     *
     * @param now 传入当前时间
     * @param repaymentPlanParam 获取还款计划参数
     * @param lastRepaymentDate 最后还款时间
     */
    public static RepaymentPlan getCurrentRepaymentPlan(LocalDate now,
        RepaymentPlanParam repaymentPlanParam,
        LocalDate lastRepaymentDate) {
        LocalDate firstStatementDate = LocalDate.parse(repaymentPlanParam.getFirstStatementDate());
        //当前时间大于最后还款时间
        RepaymentFormulaInterface repaymentFormulaInterface = new RepaymentFormulaInterface() {
        };
        List<RepaymentPlan> repaymentPlans = repaymentFormulaInterface
            .getRepaymentPlans(repaymentPlanParam);
        if (now.compareTo(lastRepaymentDate) > 0) {
            return repaymentPlans.get(repaymentPlanParam.getTerm() - 1);
        }
        long between = ChronoUnit.MONTHS.between(firstStatementDate, now);
        if (between < 0) {
            throw new NullPointerException("还款计划生成失败，当前时间少于首次账单日");
        }
        if (between == 0) {
            //第一期
            return repaymentPlans.get(0);
        } else if (between >= repaymentPlanParam.getTerm()) {
            return repaymentPlans.get(repaymentPlanParam.getTerm() - 1);
        } else {
            //获取对比这个月的账单日
            LocalDate localDate = firstStatementDate.plusMonths(between + 1);
            if (now.compareTo(localDate) >= 0) {
                //大于等于取出的账单日则为取出期数
                //返回对比期数
                return repaymentPlans.get((int) between + 1);
            } else {
                //小于对比期数
                //返回对比上一期
                return repaymentPlans.get((int) (between));
            }
        }
    }

    public static void main(String[] args) {
        LocalDate now = LocalDate.now();
        LocalDate firstStatementDate = LocalDate.parse("2020-02-10");
        System.out.println(firstStatementDate.plusMonths(36));
        long between = ChronoUnit.MONTHS.between(firstStatementDate, now);
        System.out.println(between);
    }
}
